<?php
/**
 * Paperclip model
 * @author dangnh6
 * $Id$
 *
 */
class SGN_Paperclip{
    const THRIFT_SUCCESS_CODE = 200;
    const THRIFT_BAD_REQUEST = 400;
    const THRIFT_FILE_NOT_EXIST = 404;
    const THRIFT_TOO_BIG = 413;
    const THRIFT_TYPE_NOT_SUPPORT = 415;
    const THRIFT_VARIANT_NOT_SUPPORT = 501;
    const CACHE_SEPARATOR = '.';
	private static $_instance = null;
	// thrift client object
	private $_thriftClient;
	// authentication key
	private $authKey;
	// module name
	private $moduleName;
	private function __construct($config) {
	    if($config){
	        $options = $config;
	    }else{
		    $thrift = SGN_Application::getConfig('sgn', 'services', 'thrift');
		    $options = array('host' => $thrift->get('daspHost'),
		    		'port' => $thrift->get('daspPort'),
		    );
	    }
	    $this->_thriftClient = SGN_ThriftTransport::factory($options, 'daspService');
	    $this->moduleName = SGN_Application::getConfig('sgn', 'services', 'paperclip')->module;
	    $this->authKey = SGN_Application::getConfig('sgn', 'services', 'paperclip')->authKey;
	}
	/**
	 * Create single instance of this class
	 * @return SGN_Paperclip
	 * */
	public static function factory($config = null) {
		if(self::$_instance == null) {
			self::$_instance = new SGN_Paperclip($config);
		}
		return self::$_instance;
	}
	
	/**
	 * get memcache instance
	 * @param string $instance
	 * @return Ambigous <Zing_Cache_Memcache, multitype:>
	 */
	protected function getCacheInstance($instance)
	{
		if ($instance) {
			return SGN_Application::loadCacheInstance('sgn', $instance);
		}
		$this->_cache = SGN_Application::loadCacheInstance('guild', 'global');
	}
	/**
	 * upload a file
	 * @param string $file_name tên của file được upload
	 * @param string $mime_type mimetype của file
	 * @param int $file_size kích thước của file 
	 * @param base64 encoded $file_content nội dung của file (base64 encoded),
	 * @param url $file_url đường dẫn tới file
	 * @param int $product_id ID/Name của product
	 * @param int $owner_id ID của user người upload file
	 * @return ("file_id": ID của file được sinh ra từ server,
                "file_status": status của file,
                "file_url": url gốc của file (nếu có đưa vào)
                "file_location": đường dẫn tương đối tới file,
                "file_realms": danh sách các server file được lưu)

	 * @throws Exception
	 * Lưu ý:
     *   -	Client có thể push nguyên nội dung của file content lên API thông qua biến file_content; hoặc đưa đường dẫn đến file qua tham số file_url để API đọc nội dung file.
     *   -	file_location (trong output) sẽ trỏ tới file chứ không phải tới thư mục chứa file, tức là /$PRODUCT/YYYY/MM/DD/HH/FILE_ID/FILE_ID.FILE_EXT
     *   -	Đường dẫn tới file có thể ở 2 dạng:
     *   o	/folder1/folder1/file: trỏ tới file trên local file system (chỉ sử dụng được khi server API và Client access tới được 1 thư mục chung).
     *   o	http://url, https://url hoặc ftp://url: đường dẫn tới external file dạng http, https hoặc ftp.
     * Input chỉ chấp nhận 1 trong 2 tham số file_content và file_url. Nếu cả 2 tham số đều có thì sẽ ưu tiên file_content.
     * Bình thường API sẽ trả về status của file là 0. Nếu file_url trỏ đến 1 file external thì API sẽ trả về status là 1 (xem thêm File Status) và quá trình download file sẽ được thực hiện sau.
	 */
	public function uploadFile($file_name, $mime_type, $file_size, $file_content, $file_url, $product_id, $owner_id)
	{
	    $functionName = 'uploadFile';
	    $encodedInput = json_encode(array('file_name' => $file_name, 'mime_type' => $mime_type, 'file_size' => $file_size, 'file_content' => $file_content, 'file_url' => $file_url, 'product_id' => $product_id, 'owner_id' => $product_id));
	    $output = $this->_thriftClient->callApi($this->moduleName, $functionName, $encodedInput, $this->authKey);
	    $result = json_decode($output, true);
		if($result['status'] == self::THRIFT_SUCCESS_CODE){
	        return $result['message'];
	    }else{
	        throw new Exception($result['message'], $result['status']);
	    }
	}
	/**
	 * get file info
	 * @param string $file_id
	 * @return array ("file_id": ID của file,
                    "file_timestamp": timestamp của file,
                    "file_realms": danh sách các server có chứa file,
                    "file_location": đường dẫn (tương đối) tới file,
                    "file_size": kích thước của file,
                    "file_mimetype": mimetype của file,
                    "file_status": status của file,
                    "file_url": url tới file gốc (nếu là external),
                    "product_id": ID/name của product,
                    "owner_id": id của user, người upload file,
                    "variants": thông tin variants của file
                    )
	 * @throws Exception
	 */
	public function getFileInfo($file_id)
	{
	    $functionName = 'getFileInfo';
	    $encodedInput = json_encode(array('file_id' => $file_id));
	    $output = $this->_thriftClient->callApi($this->moduleName, $functionName, $encodedInput, $this->authKey);
	    $result = json_decode($output, true);
	    if($result['status'] == self::THRIFT_SUCCESS_CODE){
	        return $result['message'];
	    }else{
	        throw new Exception($result['message'], $result['status']);
	    }
	}
	/**
	 * delete a file
	 * @param string $file_id
	 * @throws Exception
	 */
	public function deleteFile($file_id)
	{
	    $functionName = 'deleteFile';
	    $encodedInput = json_encode(array('file_id' => $file_id));
	    $output = $this->_thriftClient->callApi($this->moduleName, $functionName, $encodedInput, $this->authKey);
	    $result = json_decode($output, true);
	    if($result['status'] == self::THRIFT_SUCCESS_CODE){
	        return $result['message'];
	    }else{
	        throw new Exception($result['message'], $result['status']);
	    }
	}
	/**
	 * delete variant file
	 * @param string $file_id
	 * @param string $variant_name
	 * @throws Exception
	 */
	public function deleteVariant($file_id, $variant_name)
	{
	    $functionName = 'deleteVariant';
	    $encodedInput = json_encode(array('file_id' => $file_id, 'variant_name' => $variant_name));
	    $output = $this->_thriftClient->callApi($this->moduleName, $functionName, $encodedInput, $this->authKey);
	    $result = json_decode($output, true);
	    if($result['status'] == self::THRIFT_SUCCESS_CODE){
	        return $result['message'];
	    }else{
	        throw new Exception($result['message'], $result['status']);
	    }
	}
	/**
	 * create variant file
	 * @param string $file_id
	 * @param string $variant_name
	 * @param array $rule - 1 list các rule
	 * @throws Exception
	 *  -	Variant name chỉ chấp nhận chữ cái (a-z, A-Z), chữ số (0-9), gạch dưới (_) và gạch ngang (-); tối đa 16 ký tự; và không được để trống.
        -	Server tự động chuyển variant name sang chữ thường. 
        -	Server trả về mã lỗi 400 (bad request) nếu variant đã tồn tại, hoặc variant name không hợp lệ.
        -	Rules đưa vào là 1 list các rule. Mỗi rule là 1 map, cụ thể như sau:
            o	{"rule": "resize", "width": int, "height": int}: rule resize cần 2 tham số width và height là 2 số nguyên dương.
        -	Nếu status của file là != 0, APi sẽ trả về lỗi

	 */
	public function createVariant($file_id, $variant_name, $rules)
	{
	    $functionName = 'createVariant';
	    $encodedInput = json_encode(array('file_id' => $file_id, 'variant_name' => $variant_name, 'rules' => $rules));
	    $output = $this->_thriftClient->callApi($this->moduleName, $functionName, $encodedInput, $this->authKey);
	    $result = json_decode($output, true);
	    if($result['status'] == self::THRIFT_SUCCESS_CODE){
	        return $result['message'];
	    }else{
	        throw new Exception($result['message'], $result['status']);
	    }
	}
}